/**
 *  axios 封装
 *  <p>封装axios请求，并添加拦截器，处理错误和返回数据</p>
 *  @since 2025-11-17 09:05:05
 *  @author 沈汝旭
 *  @version 1.0.0
 */
import axios from 'axios'
import type { AxiosInstance} from 'axios'
import { ElMessage } from 'element-plus'


/**
 * ✅ 1. 创建 axios 实例（基础配置，直接复制可用）
 * 关键点：设置基础 URL 和超时时间
 */
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL, // 从 .env 文件读取
  timeout: 15000, // 15秒超时（避免卡住）
  headers: { 'Content-Type': 'application/json' }
})


// 请求拦截器
service.interceptors.request.use(config => {
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
}, error => {
  return Promise.reject(error)
})


// 响应拦截器
service.interceptors.response.use(
    response => {
      // ✅ 直接返回数据（不处理类型，避免 'data' is unknown 错误）
      return response.data
    },
    error => {
      // 1. 服务器返回了响应（有 status）
      if (error.response) {
        const { status, data } = error.response
        const message = (data as any)?.message || data || '请求失败'

        // 401 未授权（自动跳转登录）
        if (status === 401) {
          localStorage.removeItem('token')
          window.location.href = '/login'
          return Promise.reject('登录过期')
        }

        // 其他错误统一提示
        ElMessage.error(`${status} ${message}`)
        return Promise.reject(message)
      }

      // 2. 网络错误（无 response）
      if (!navigator.onLine) {
        ElMessage.error('当前无网络，请检查网络设置')
        return Promise.reject('网络错误')
      }

      // 3. 请求超时
      if (error.code === 'ECONNABORTED') {
        ElMessage.error('请求超时，请重试')
        return Promise.reject('超时')
      }

      // 4. 其他错误
      ElMessage.error(`请求失败: ${error.message}`)
      return Promise.reject(error.message)
    }
)

/**
 * ✅ 4. API 封装（直接调用，无需指定泛型）
 * 用法：get('/api/users')  // 不需要 <User[]> ！
 */
export const get = (url: string, params?: object) =>
    service.get(url, { params })

export const post = (url: string, data?: object) =>
    service.post(url, data)

export const put = (url: string, data?: object) =>
    service.put(url, data)

export const del = (url: string, params?: object) =>
    service.delete(url, { params })